module sdldee.video.videosurface;

import std.string;

import sdldee.c.sdl;
public import sdldee.video.surface;
import sdldee.video.videoinfo;
import sdldee.video.rectangle;
import sdldee.video.pixelformat;
import sdldee.video.exception;

class VideoSurface : Surface {
	private this(SDL_Surface* surface) {
		super(surface);
	}
	
	private static VideoSurface singleton = null;
	
	this(int width, int height, int bpp, uint flags) {
		SDL_Surface* surface = SDL_SetVideoMode(width, height, bpp, flags);
		if(surface == null)
			throw new VideoException("Unable to set video mode");
		super(surface);
		singleton = this;
	}

	public static VideoSurface videoSurface() {
		return singleton;
	}
	
	public static VideoInfo videoInfo() {
		return new VideoInfo(SDL_GetVideoInfo());
	}
	
	public static int videoModeOk(int width, int height, int bpp, uint flags) {
		return SDL_VideoModeOK(width, height, bpp, flags);
	}
	
	public static Rectangle[] listModes(PixelFormat format, uint flags) {
		SDL_Rect** modes = SDL_ListModes(format.cformat, flags);
		Rectangle[] rects;
		
		if(modes == cast(SDL_Rect **) -1)
			return null;
		
		for(int i = 0; modes[i] ; ++i) {
			rects.length = rects.length + 1;
			rects[i - 1] = new Rectangle(modes[i]);
		}
		
		return rects;
	}
	
	public static char[] videoDriverName() {
		char* buff = (new char[256]).ptr;
		return std.string.toString(SDL_VideoDriverName(buff, 255));
	}
	
	public void updateRectangle(Rectangle rect) {
		SDL_UpdateRect(csurface, rect.x, rect.y, rect.w, rect.h);
	}
	
	public void updateRects(Rectangle[] rects) {
		SDL_Rect[] sdlrects;
		sdlrects.length = rects.length;
		for(int i = 0; i < rects.length; i++)
			sdlrects[i] = *rects[i].crect;
		SDL_UpdateRects(csurface, sdlrects.length, sdlrects.ptr);
	}
	
	public void flip() {
		if(SDL_Flip(csurface) < 0)
			throw new VideoException("Unable to flip buffers");
	}
	
	public static void setGamma(float red, float green, float blue) {
		if(SDL_SetGamma(red, green, blue) < 0)
			throw new VideoException("Unable to set gamma");
	}
	
	public static void setGammaRamp(ushort[256] red, ushort[256] green, ushort[256] blue) {
		if(SDL_SetGammaRamp(red.ptr, green.ptr, blue.ptr) < 0)
			throw new VideoException("Unable to set gamma ramp");
	}
	
	public static void getGammaRamp(out ushort[] red, out ushort[] green, out ushort[] blue) {
		red.length = 256;
		green.length = 256;
		blue.length = 256;
		if(SDL_GetGammaRamp(red.ptr, green.ptr, blue.ptr) < 0)
			throw new VideoException("Unable to get gamma ramp");
	}
}
